<template>
	<div
		id="mapContainer"
		style="height: calc(100vh - 85px)"
		v-loading="state.mapLoading"
		element-loading-text="加载中..."
	>
		<div class="map_btn_container">
			<el-button type="warning" size="large" class="map_btn" @click="onAnimation">播放动画</el-button>
			<el-button type="success" size="large" class="map_btn" @click="onFitMap">还原缩放</el-button>
			<el-button type="primary" size="large" class="map_btn" @click="onResetMap">初 始 化</el-button>
		</div>
	</div>
</template>

<script setup lang="ts" name="map">
import { reactive, onMounted } from "vue";
import { ElMessage } from "element-plus";
import { createMap, createPath, createMarker, moveCarMarker, analyseRoute, fitBounds } from "/@/utils/TMap";
import { carPositionList, orderData } from "/@/utils/TMapData";

const state = reactive({
	mapLoading: false,
	carPositionList: [] as PointerType[],
	bounds: [] as EmptyArrayType, // 地图边界限制
	coords: [] as EmptyArrayType, // 车辆预计路线
});
let map: EmptyObjectType = {}; // 地图图层
let marker: EmptyObjectType = {}; // 标记图层
let polyline: EmptyObjectType = {}; // 折线图层

// 使用 Promise 和 setTimeout 模拟异步请求
const getCarPositionList = () => {
	return new Promise<PointerType[]>(resolve => {
		setTimeout(() => {
			resolve(carPositionList);
		}, 500);
	});
};

const TMap = window.TMap;
// 初始化地图
const initMap = async () => {
	// 创建地图实例
	map = createMap(23.00944, 113.12249); // 默认以广东佛山为地图渲染中心
	map.removeControl(TMap.constants.DEFAULT_CONTROL_ID.ZOOM); // 移除地图缩放控件
	// 获取所有救护车的位置坐标
	try {
		state.carPositionList = await getCarPositionList();
		initMarker(state.carPositionList);
	} catch {
		ElMessage.warning("救护车位置获取失败，请刷新重试");
	}
};
// 清空地图数据
const clearMap = () => {
	// map.stopAnimation(); // 停止地图动画
	marker.stopMove(); // 停止标记移动
	marker.setMap && marker.setMap(null); // 清空标记图层
	polyline.setMap && polyline.setMap(null); // 清空折线图层
	state.bounds = []; // 清空地图边界限制
};
// 添加标记点
const initMarker = (pointArray: PointerType[]) => {
	marker = createMarker(pointArray, map);
	onFitMap(pointArray);
};
// 添加车辆预计路线的轨迹
const initCarPath = (polylineArray: number[]) => {
	state.coords = analyseRoute(polylineArray);
	polyline = createPath(state.coords, map, true);
};
// 触发车辆的行驶动画
const initCarMoving = async (carPoint: PointerType) => {
	let oldCoords: EmptyArrayType = [];
	/* 模拟分段 */
	// oldCoords = randomCoords[2].map(item => {
	// 	return new TMap.LatLng(item.lat, item.lng);
	// });
	// for (let i = 0; i < randomCoords.length; i++) {
	// 	let newCoords = randomCoords[i].map(item => {
	// 		return new TMap.LatLng(item.lat, item.lng);
	// 	});
	// 	await moveCarMarker(carPoint, newCoords, oldCoords, marker, polyline);
	// 	oldCoords = newCoords;
	// }
	/* 模拟全程 */
	moveCarMarker(carPoint, state.coords, oldCoords, marker, polyline);
};

// 地图自适应缩放
const onFitMap = (pointArray?: PointerType[]) => {
	if (pointArray && pointArray.length > 0) {
		state.bounds = state.bounds.concat(
			pointArray.map(item => {
				return new TMap.LatLng(item.lat, item.lng);
			})
		);
	}
	fitBounds(state.bounds, map, "home");
};
// 地图复位
const onResetMap = async () => {
	state.mapLoading = true;
	clearMap();
	try {
		state.carPositionList = await getCarPositionList();
		initMarker(state.carPositionList);
	} catch {
		ElMessage.warning("救护车位置获取失败，请刷新重试");
	}
	state.mapLoading = false;
};
// 播放动画
const onAnimation = () => {
	clearMap();
	initCarPath(orderData.routes.polyline);
	const startPoint: PointerType = {
		id: orderData.order.start_position,
		pointType: "model_start",
		lat: Number(orderData.order.start_x),
		lng: Number(orderData.order.start_y),
	};
	const endPoint: PointerType = {
		id: orderData.order.end_position,
		pointType: "model_end",
		lat: Number(orderData.order.end_x),
		lng: Number(orderData.order.end_y),
	};
	const carPoint: PointerType = {
		id: orderData.order.car_no,
		pointType: "move_ambulance_1",
		lat: state.coords[0].lat,
		lng: state.coords[0].lng,
	};
	initMarker([carPoint, startPoint, endPoint]);
	initCarMoving(carPoint);
};

onMounted(() => {
	initMap();
});
</script>

<style scoped lang="scss">
#mapContainer {
	position: relative;
	.map_btn_container {
		position: absolute;
		right: 10px;
		bottom: 0;
		z-index: 1999;
		display: flex;
		flex-direction: column;
		.map_btn {
			margin: 0 0 10px;
		}
	}
}
</style>
